package com.ruoyi.stock2.thread.aboutDownloadData;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.stock2.domain.DownTradedataSchedule;
import com.ruoyi.stock2.domain.STOCK;
import com.ruoyi.stock2.domain.TRADEDATA;
import com.ruoyi.stock2.mapper.DownTradedataScheduleMapper;
import com.ruoyi.stock2.mapper.STOCKMapper;
import com.ruoyi.stock2.mapper.TRADEDATAMapper;
import com.ruoyi.stock2.utils.DateUtils2;

public class CompPingjun3 {
	private static final Logger log = LoggerFactory.getLogger(CompPingjun3.class);
	String beginDateTime = "";
	DownTradedataScheduleMapper downLoadTradedataScheduleMapper;
	TRADEDATAMapper tradedataMapper;

	// 单例实现
	public static CompPingjun3 getInstance() {
		return Singtonle.instance;
	}

	private static class Singtonle {
		private static CompPingjun3 instance = new CompPingjun3();
	}

	public void run() {

		downLoadTradedataScheduleMapper = (DownTradedataScheduleMapper) SpringUtils.getBean(DownTradedataScheduleMapper.class);
		tradedataMapper = (TRADEDATAMapper) SpringUtils.getBean(TRADEDATAMapper.class);
		compPingjun();
		beginDateTime = "";
	}

	// 测试有返回结果
	private void compPingjun() {
		STOCKMapper stockService = (STOCKMapper) SpringUtils.getBean(STOCKMapper.class);
		List<STOCK> stocks = stockService.selectSTOCKList(null);

		DownTradedataSchedule ac = downLoadTradedataScheduleMapper.selectDownTradedataScheduleByName("update_average_schedule");
		
		for (STOCK stock : stocks) {
			if(stock.getSymbol().compareTo(ac.getValue())<0){
				continue;
			}

			if ("2004-01-01".equals(getBeginDateTime())) {
				TRADEDATA tradeDataKey = new TRADEDATA(stock.getSymbol(),
						DateUtils2.formatStringToDate("2004-01-01", "yyyy-MM-dd"));

				List<TRADEDATA> list = tradedataMapper.getByKeyDateTimeDesc(tradeDataKey);
				completeVolumeAndaragPrice(list, tradeDataKey.getDatetime());
				list = null;

			} else {
				//索引是根据symbol datetime所建立，所以缺少一个字段查询会变慢很多
				TRADEDATA tradeDataKey = new TRADEDATA(stock.getSymbol(),
						DateUtils2.formatStringToDate("2004-01-01", "yyyy-MM-dd"));
				List<TRADEDATA> list = tradedataMapper.get200ByKeyDateTimeDesc(tradeDataKey);
				completeVolumeAndaragPrice(list, DateUtils2.formatStringToDate(beginDateTime, "yyyy-MM-dd"));
				list = null;
			}

			downLoadTradedataScheduleMapper.updateDownTradedataSchedule(
					new DownTradedataSchedule("update_average_schedule", stock.getSymbol()));
			
		}
	}

	public String getBeginDateTime() {
		return beginDateTime;
	}

	public void setBeginDateTime(String beginDateTime) {
		this.beginDateTime = beginDateTime;
	}

	/**
	 * @return 更新数据库的平均价格及平均交易量
	 * @param list
	 *            中包含为200天的记录 或 历史中所有的记录
	 */
	public void completeVolumeAndaragPrice(List<TRADEDATA> list, Date beginDateTime) {
		//List<TRADEDATA> temp1 = new ArrayList<TRADEDATA>(30);
		//ConcurrentLinkedQueue<TRADEDATA> concurrentLinkedQueue = new ConcurrentLinkedQueue<TRADEDATA>();
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).getDatetime().compareTo(beginDateTime) >= 0) {
				TRADEDATA tradeData = new TRADEDATA();
				BeanUtils.copyProperties(list.get(i), tradeData);
				tradeData.setDatetime(list.get(i).getDatetime());
				tradeData.setSymbol(list.get(i).getSymbol());
				tradeData.setZhang(ZhangFun(list, i));
				tradeData.setZhangfu(ZhangfuFun(list, i));
				if (list.size() - i >= 5)
					tradeData.setVolume5(pingJunFun(list, 5, i, "volume"));
				else
					tradeData.setVolume5(null);
				if (list.size() - i >= 10)
					tradeData.setVolume10(pingJunFun(list, 10, i, "volume"));
				else
					tradeData.setVolume10(null);
				if (list.size() - i >= 5)
					tradeData.setAverageprice5(pingJunFun(list, 5, i, "closePrice"));
				else
					tradeData.setAverageprice5(null);
				if (list.size() - i >= 10)
					tradeData.setAverageprice10(pingJunFun(list, 10, i, "closePrice"));
				else
					tradeData.setAverageprice10(null);
				if (list.size() - i >= 20)
					tradeData.setAverageprice20(pingJunFun(list, 20, i, "closePrice"));
				else {
					tradeData.setAverageprice20(null);
				}
				if (list.size() - i >= 60)
					tradeData.setAverageprice60(pingJunFun(list, 60, i, "closePrice"));
				else
					tradeData.setAverageprice60(null);

				this.tradedataMapper.updateTRADEDATA(tradeData);
				//concurrentLinkedQueue.offer(tradeData);
				
			} else {
				break;
			}
			
		}
		
//		if(!concurrentLinkedQueue.isEmpty()) {
//        	while (!concurrentLinkedQueue.isEmpty()){
//				temp1.add(concurrentLinkedQueue.poll());
//				if( temp1.size() == 10 ) {
//					tradedataMapper.updateBatch(temp1);
//					temp1.clear();
//				}
//			}
//
//        	if(temp1.size() > 0) {
//            	tradedataMapper.updateBatch(temp1);
//            	temp1.clear();
//            }
//        }

//		concurrentLinkedQueue = null;
/*		if (list != null) {
			WeakReference<List<TRADEDATA>> gc1 = new WeakReference<List<TRADEDATA>>(list);
			int ii = 1;
			list = null;
			while (gc1.get() != null && ii != 3) {
				System.gc();
				ii++;
			}
		}*/
	}

	/*
	 * 通用计算平均值
	 */
	public BigDecimal pingJunFun(List<TRADEDATA> ls, int size, int num, String volumeOrClosePrice) {
		BigDecimal reback = new BigDecimal(0);
		for (int i = num; i < (num + size); i++) {
			if ("volume".equals(volumeOrClosePrice) && i < ls.size()) {
				reback = reback.add(new BigDecimal(ls.get(i).getVolume().toString()));
			} else if ("closePrice".equals(volumeOrClosePrice) && i < ls.size()) {
				reback = reback.add(new BigDecimal(ls.get(i).getCloseprice().toString()));
			}
		}
		return reback.divide(new BigDecimal(size), 2, BigDecimal.ROUND_HALF_UP);
	}

	/*
	 * 通用计算差值
	 */
	public BigDecimal ZhangFun(List<TRADEDATA> ls, int num) {
		BigDecimal yesterDayPrice = new BigDecimal(0);
		BigDecimal todayPrice = new BigDecimal(0);
		if (num + 1 < ls.size()) {
			todayPrice = new BigDecimal(ls.get(num).getCloseprice().toString());
			yesterDayPrice = new BigDecimal(ls.get(num + 1).getCloseprice().toString());
		}
		return todayPrice.subtract(yesterDayPrice).setScale(2, BigDecimal.ROUND_HALF_UP);
	}

	/*
	 * 通用计算涨幅
	 */
	public BigDecimal ZhangfuFun(List<TRADEDATA> ls, int num) {
		BigDecimal yesterDayPrice = new BigDecimal(0);
		BigDecimal todayPrice = new BigDecimal(0);
		BigDecimal result = new BigDecimal(0);
		if (num + 1 < ls.size()) {
			todayPrice = new BigDecimal(ls.get(num).getCloseprice().toString());
			yesterDayPrice = new BigDecimal(ls.get(num + 1).getCloseprice().toString());
			result = todayPrice.subtract(yesterDayPrice).divide(yesterDayPrice, 4, BigDecimal.ROUND_HALF_UP)
					.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
		}
		return result;
	}

}
